#include<iostream>
using namespace std;
#define MAX 1000


struct free_table//结构体
{
	string name;    //区名
	int start;
	int length;
	int END;
	int status;   //定义分区状态 0表示未分配  1表示已分配   -1 表示空表目

};
struct free_table table[MAX];
int p = 0;
//初始化
void init() {
	for (int i = 0; i < MAX; i++)
		table[i].status = -1;
	table[0].name = "系统";
	table[0].start = 0;
	table[0].length = 10;
	table[0].END = 9;
	table[0].status = 1;

	table[1].name = "空闲区1";
	table[1].start = 10;
	table[1].length = 10;
	table[1].END = 19;
	table[1].status = 0;

	table[2].name = "作业2";
	table[2].start = 20;
	table[2].length = 25;
	table[2].END = 44;
	table[2].status = 1;

	table[3].name = "空闲区2";
	table[3].start = 45;
	table[3].length = 20;
	table[3].END = 64;
	table[3].status = 0;

	table[4].name = "作业3";
	table[4].start = 65;
	table[4].length = 45;
	table[4].END = 109;
	table[4].status = 1;

	table[5].name = "空闲区3";
	table[5].start = 110;
	table[5].length = 146;
	table[5].END = 255;
	table[5].status = 0;

}

void print_free_table() {
	for (int i = 0; i < MAX; i++)
	{
		if (table[i].status == 0) {
			cout << "空闲区如下："<<endl;
			cout << "   name   begin   size   end   statue"<<endl;
			cout << "  " << table[i].name << "  " << table[i].start << "     " << table[i].length << "	" << table[i].END << "	" << table[i].status << endl;
		}
	}
	

}
void print_job_table() {
	for (int i = 0; i < MAX; i++)
	{
		if (table[i].status == 1) {
			cout << "分配区如下："<<endl;
			cout << "   name   begin   size   end   status"<<endl;
			cout << "  " << table[i].name << "	   " << table[i].start << "	  " << table[i].length << "	" << table[i].END << "	" << table[i].status << endl;
		}
	}
	
}
//最佳适应
void best_fit(int a, string name, int worksize)
{
	//从后往前把在a地址后的所有分区往后退一个分区，目的在于增加一个分区
	for (int i = MAX; i > a + 1; i--)
	{
		if (table[i - 1].status == -1)
			continue;
		table[i] = table[i - 1];

	}
	if (worksize == table[a].length) 
	{
		table[a + 1].status = -1;
		table[a].name = name;
		table[a].length = worksize;
		table[a].END = table[a].start + table[a].length - 1;
		table[a].status = 1;
	}else
	{
		table[a + 1].name = "空闲";
		table[a + 1].start = table[a].start + worksize;
		table[a + 1].length = table[a].length - worksize;
		table[a + 1].END = table[a].END;
		table[a + 1].status = 0;

		table[a].name = name;
		table[a].length = worksize;
		table[a].END = table[a].start + table[a].length - 1;
		table[a].status = 1;
	}
	
}
//分配
void allocation() {

	int    i;
	int    a;
	int    worksize;
	string workname;
	int    pFree;
	cout << endl<<"请输入作业名称：";
	cin >> workname;
	for (i = 0; i < MAX; i++)
	{
		if (table[i].name == workname)//判断作业名称是否已经存在
		{
			cout<<endl<<"作业已经存在，不必再次分配！"<<endl;
			return;
		}
	}
	cout << "请输入作业大小（单位：K）：";
	cin >> worksize;
	for (i = 0; i < MAX; i++)//通过循环在空闲区找是否有适合区间存储作业
	{
		if (table[i].status == 0 && table[i].length >= worksize)
		{
			pFree = i;
			break;
		}
	}
	if (i == MAX)
	{
		cout<<endl<<"该作业大小超出最大可分配空间";
		
		return;
	}
	for (i = 0; i < MAX; i++)//最佳适应算法
		if (table[i].status == 0 && table[i].length >= worksize)
			if (table[pFree].length > table[i].length)
				pFree = i;//找到最小空闲分区进行分配
	best_fit(pFree, workname, worksize);

	cout << endl<<"分配成功"<<endl;
	
}
//合并连续的空闲区
void combine() {         

	int i = 0;
	while (i != MAX - 1)
	{
		for (i = 0; i < MAX - 1; i++)
		{
			if (table[i].status == 0)
				if (table[i + 1].status == 0)
				{
					table[i].length = table[i].length + table[i + 1].length;
					table[i].END = table[i].start + table[i].length - 1;
					i++;//依次往前 如果空表的话要改状态
					for (i; i < MAX - 1; i++)
					{
						if (table[i + 1].status == -1)
						{
							table[i].status = -1;
							break;
						}

						table[i] = table[i + 1];
					}
					table[MAX - 1].status = -1;
					break;
				}
		}
	}
}
void recycle()  //用于回收作业
{        
	int i;
	int number;
	string name;
	int n = 0;
	cout << "请输入要回收的作业或进程：";
	cin >> name;
	if (name == "系统")
	{
		cout << "系统分区，不可回收！" << endl;
		return;

	}
	for (i = 0; i < MAX; i++) {
		if (table[i].status == 1)
		{
			if (name == table[i].name) {
				table[i].name = "空闲区";
				table[i].status = 0;

			}

		}
	}
	if (i == MAX - 1)
	{
		cout << "找不到分区"<<endl;
		return;
	}
	combine();        //合并连续空闲区
	cout << "回收成功！"<<endl;
	

}

int main()
{
	int selection;
	init();
	cout<<"初始化完成，设内存容量"<<MAX;

	cout << "----------------------------" << endl;
		cout << "   1. 打印空闲表   " << endl;
		cout << "   2. 打印已分配表   " << endl;
		cout << "   3. 分配分区   " << endl;
		cout << "   4. 回收分区   " << endl;
		cout << "   5. 退出系统   " << endl;
		cout << "----------------------------" << endl;

		
	while (1) {
		
		cout <<endl<< "请输入选择的序号："<<endl;
		while (1) {
			cin >> selection;
			if (selection == 1 || selection == 2 || selection == 3 || selection == 4 || selection == 5)
				break;
			cout<<"输入错误，请重新输入：";
		}
		switch (selection)
		{
		case 1:
			print_free_table();
			break;
		case 2:
			print_job_table();
			break;
		case 3:
			allocation();
			break;
		case 4:
			recycle();
			break;
		case 5:
			exit(0);
			break;
		default:
			break;
		}
	}

}


